package com.google.code.bankagregator.dao;

import com.google.code.bankagregator.entities.Deposit;
import com.google.code.bankagregator.entities.State;

import javax.ejb.Stateless;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Deposit CrudDAO class
 * User: kaiser
 */
@Stateless
public class DepositDAO extends DAO {

    private final Logger log = Logger.getLogger(DepositDAO.class.getName());

    public void update(Deposit entity) {
        try {
            Deposit deposit = getDepositId(entity);
            entity.setId(deposit.getId());
        } catch (NoResultException ex) {
            log.log(Level.INFO, "New deposit entity " + entity.toString());
        }
        entity.setAdded(new Date());
        getEntityManager().merge(entity);
    }

    /**
     * Search for ID for data from parser
     *
     * @param entity form parser
     * @return value object
     */
    public Deposit getDepositId(Deposit entity) {
        Query query = getEntityManager()
                .createQuery("SELECT c FROM Deposit c WHERE " +
                        "c.name = :name AND " +
                        "c.url = :url AND " +
                        "c.state = :state AND " +
                        "c.currency = :currency AND " +
                        "c.maxAmount = :maxAmount AND " +
                        "c.minAmount = :minAmount AND " +
                        "c.term = :term AND " +
                        "c.refill = :refill AND " +
                        "c.type = :dtype ");

        query.setParameter("name", entity.getName());
        query.setParameter("url", entity.getUrl());
        query.setParameter("state", entity.getState());
        query.setParameter("currency", entity.getCurrency());
        query.setParameter("maxAmount", entity.getMaxAmount());
        query.setParameter("minAmount", entity.getMinAmount());
        query.setParameter("term", entity.getTerm());
        query.setParameter("refill", entity.isRefill());
        query.setParameter("dtype", entity.getType());

        return (Deposit) query.getSingleResult();
    }

    public void delete(Deposit entity) {
        Deposit deletedApplicant = entity;
        if (!getEntityManager().contains(entity)) {
            deletedApplicant = getEntityManager().merge(entity);
        }

        getEntityManager().remove(deletedApplicant);
    }

    public void delete(int id) {
        Deposit deposit = getById(id);
        delete(deposit);
    }

    public void create(Deposit entity) {
        getEntityManager().persist(entity);
    }

    public Deposit getById(int id) {
        return getEntityManager().find(Deposit.class, id);
    }

    public List<Deposit> getAll() {
        return getEntityManager().createQuery("SELECT d FROM Deposit d").getResultList();
    }

    public List<Deposit> getActive() {
        Query query = getEntityManager()
                .createQuery("SELECT d FROM Deposit d WHERE " +
                        "d.state <> :archive ");

        query.setParameter("archive", State.ARCHIVE);

        return query.getResultList();
    }

    public List<Deposit> getByAccurateCriteria(Deposit criteria,int amount) {

       Query query= getEntityManager()
                .createQuery("SELECT d FROM Deposit d WHERE d.term =:term AND d.currency = :currency AND :amount>=d.minAmount");

        query.setParameter("term",criteria.getTerm()*31);
        query.setParameter("amount",amount);
        query.setParameter("currency", criteria.getCurrency());
        return query.getResultList();
    }
    public List<Deposit> getByInaccurateCriteria(Deposit criteria,int amount) {

        Query query= getEntityManager()
                .createQuery("SELECT d FROM Deposit d WHERE d.term > :minTerm and  d.term <=:maxTerm AND d.currency = :currency AND :amount>=d.minAmount");

        query.setParameter("minTerm",(criteria.getTerm()*31)-62);
        query.setParameter("maxTerm",(criteria.getTerm()*31)+62);
        query.setParameter("amount",amount);
        query.setParameter("currency", criteria.getCurrency());
        return query.getResultList();
    }
}
